# -*- coding: utf8 -*-
"""
Hopf algebra : Parking functions Quasisymetric.

AUTHOR:

- Jean-Baptiste Priez
"""
#*****************************************************************************
#       Copyright (C) 2012 Jean-Baptiste Priez <jbp@kerios.fr>,
#
#  Distributed under the terms of the GNU General Public License (GPL)
#
#    This code is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    GERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#    General Public License for more details.
#
#  The full text of the GPL is available at:
#
#                  http://www.gnu.org/licenses/
#*****************************************************************************
from good_hopf_algebra import GoodHopfAlgebras
from pattern import FundamentalBasis, FundamentalDualBasis, \
    getitem_for_wordlike_indices
from sage.categories.graded_hopf_algebras_with_basis import \
    GradedHopfAlgebrasWithBasis
from sage.categories.realizations import Category_realization_of_parent
from sage.combinat.free_module import CombinatorialFreeModule
from sage.misc.bindable_class import BindableClass
from sage.structure.parent import Parent
from sage.structure.unique_representation import UniqueRepresentation


class ParkingQuasisymmetricFunctions( UniqueRepresentation, Parent ):

    def __init__( self, R ):
        from sage.categories.all import Rings
        assert( R in Rings() )
        self._base = R
        Parent.__init__( self, category = GoodHopfAlgebras( R ).WithRealizations() )

    def phi( self, indice ):
        '''
        TESTS::
        
            sage: PQSym(QQ).phi([3,3,1])
            [2, 2, 1]
            sage: PQSym(QQ).phi([3,3,15])
            [1, 1, 3]
        '''
        from parking_functions import to_park
        return to_park( indice )

    def indices( self ):
        '''
        EXAMPLES::
            
            sage: PQSym(QQ).indices()
            Parking Functions
        '''
        from parking_functions import ParkingFunctions
        return ParkingFunctions()

    def shift( self, pf1, pf2 ):
        '''
        EXAMPLES::
        
            sage: PQSym(QQ).shift([1,1,3,3], [1,1,3])
            [4, 4, 6]
        '''
        return [i + len( pf1 ) for i in pf2]

    def _repr_( self ):
        r"""
        EXAMPLES::

            sage: ParkingQuasisymmetricFunctions(QQ)
            Hopf algebra of Parking Quasi-Symmetric Functions over the Rational Field
        """
        return "Hopf algebra of Parking Quasi-Symmetric Functions over the %s" % self.base_ring()

    def a_realization( self ):
        return self.F()

    def __init_extra__( self ):
        pass



    _shorthands = set( ['F', 'G'] )

    class Bases( Category_realization_of_parent ):

        def super_categories( self ):
            R = self.base().base_ring()
            return [GoodHopfAlgebras( R ).Realizations(),
                    GradedHopfAlgebrasWithBasis( R ).Realizations()]

        class ParentMethods:
            pass

    class Fundamental( BindableClass, FundamentalBasis ):
        def __init__( self, PQSym ):
            '''
            TESTS::
            
                sage: F = PQSym(QQ).Fundamental()
                sage: F[1,2] * F[1,1]
                F[1, 2, 3, 3] + F[1, 3, 2, 3] + F[1, 3, 3, 2] + F[3, 1, 2, 3] + F[3, 1, 3, 2] + F[3, 3, 1, 2]
                sage: F[3,1,3,2].coproduct()
                F[] # F[3, 1, 3, 2] + F[1] # F[1, 3, 2] + F[2, 1] # F[2, 1] + F[2, 1, 2] # F[1] + F[3, 1, 3, 2] # F[]
            '''
            FundamentalBasis.__init__( self, PQSym )
            self.print_options( prefix = "F",
                    latex_prefix = "F",
                    bracket = False )

    F = Fundamental

    class FundamentalDual( BindableClass, FundamentalDualBasis ):
        def __init__( self, PQSym ):
            '''

            TESTS::
            
                sage: G = PQSym(QQ).G()
                sage: G[1,2] * G[1,1]
                G[1, 2, 1, 1] + G[1, 2, 2, 2] + G[1, 2, 3, 3] + G[1, 3, 1, 1] + G[1, 3, 2, 2] + G[1, 4, 1, 1] + G[1, 4, 2, 2] + G[2, 3, 1, 1] + G[2, 4, 1, 1] + G[3, 4, 1, 1]
                sage: G[4,1,2,5,2].coproduct()
                G[] # G[4, 1, 2, 5, 2] + G[1] # G[3, 1, 4, 1] + G[1, 2, 2] # G[1, 2] + G[4, 1, 2, 2] # G[1] + G[4, 1, 2, 5, 2] # G[]
            '''
            FundamentalDualBasis.__init__( self, PQSym )
            self.print_options( prefix = "G",
                    latex_prefix = "\\mathbb{G}",
                    bracket = False )

    G = FundamentalDual

